﻿# -*- codeing = utf-8 -*-
# @Time: 2021/10/15 18:57
# @Author: Ivan
# @File: 16-面向对象.py
# @Software: PyCharm

'''
类：对一群具有相同 特征 或者 行为 的事物的一个统称，是抽象的，不能直接使用
特征：属性
行为：方法

对象：由类创建出来的一个具体存在，可以直接使用

类是模板，对象类这个模板创建出来的，先有类，再有对象
类只有一个，对象可以有多个

类的设计：
类名：大驼峰命名法
属性：类有那些特征
方法：类有那些行为

使用dir(标识符/数据)可以查看对象内的所有属性及方法

初始化方法：
为对象分配内存空间--创建对象
为对象的属性设置初始值--初始化方法__init__(内置方法)

内置方法：
__del__：对象从内存中销毁前，会自动调用__del__
__str__：输出对象自定义的内容
'''



class Cat:
    # 内置方法，创建对象时会自动调用
    def __init__(self, name):
        print('这是初始化方法')
        self.name = name

    # 内置方法，销毁前会自动调用
    def __del__(self):
        print('%s 销毁前调用了' % self.name)

    def __str__(self):
        # 必须返回字符串
        return '我是:%s' % self.name

    # 第一个参数必须是self，其他参数放在后面
    def eat(self):
        print('%s 爱吃鱼' % self.name)

    def drink(self):
        print('%s 要吃鱼' % self.name)

# tom = Cat('tom')
# tom.eat()
# tom.drink()
# print(tom)
# print('%d' % id(tom)) # 对像存放的内存地址

# 删除(销毁)对象
# del tom
# print('=' * 20)


class Person:
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight
    def __str__(self):
        return '我的名字叫 %s, 体重是 %.2f 公斤' % (self.name, self.weight)

    def run(self):
        print('%s 爱跑步, 跑步锻炼身体' % self.name)
        self.weight -= 0.5

    def eat(self):
        print('%s 爱吃东西, 吃完东西再锻炼' % self.name)
        self.weight += 1

# xiaoming = Person('小明', 75)
# xiaoming.run()
# xiaoming.eat()
# print(xiaoming)



class HouseItem:
    def __init__(self, name, area):
        self.name = name
        self.area = area
    def __str__(self):
        return '%s 占地 %.2f 平米' % (self.name, self.area)

class House:
    def __init__(self, house_type, area):
        self.house_type = house_type
        self.area = area
        # 剩余面积
        self.free_area = area
        # 家具列表
        self.item_list = []
    def __str__(self):
        return '户型：%s\n总面积：%.2f[剩余：%.2f]\n家具：%s' \
               % (self.house_type, self.area, self.free_area, self.item_list)

    def add_item(self, item):
        # 判断家具面积
        if item.area > self.free_area:
            print('%s 面积太大了, 无法添加' % item.name)
            return
        # 添加家具
        self.item_list.append(item.name)
        # 计算剩余面积
        self.free_area -= item.area
        print('添加了：%s' % item)

# 创建家具
# bed = HouseItem('席梦思', 4)
# chest = HouseItem('衣柜', 2)
# table = HouseItem('餐桌', 1.5)
# print(bed)
# print(chest)
# print(table)
# 创建房子
# house = House('两室一厅', 60)
# house.add_item(bed)
# house.add_item(chest)
# house.add_item(table)
# print(house)



class Gun:
    def __init__(self, model):
        # 枪的型号
        self.model = model
        # 子弹数量
        self.bullet_count = 0
    # 添加子弹
    def add_bullet(self, count):
        self.bullet_count += count
    # 发射子弹
    def shoot(self):
        # 判断子弹数量
        if self.bullet_count <= 0:
            print('%s 没有子弹了' % self.model)
            return
        # 发射子弹 bullet_count-1
        self.bullet_count -= 1
        # 提示发射
        print('%s 突突突, 剩余 %d 发子弹' % (self.model, self.bullet_count))


class Soldier:
    def __init__(self, name):
        # 姓名
        self.name = name
        # 新兵没有枪
        self.gun = None
    def fire(self):
        # 判断是否有枪
        if self.gun is None:  # 建议判断为None时使用is而不是==
            print('%s 还没有枪...' % self.name)
            return
        # 喊口号
        print('冲啊...%s' % self.name)
        # 装子弹
        self.gun.add_bullet(20)
        # 开火
        self.gun.shoot()

# 创建枪
# ak47 = Gun('ak47')
# ak47.add_bullet(20)
# ak47.shoot()

# 创建许三多
# xusanduo = Soldier('许三多')
# xusanduo.gun = ak47
# xusanduo.fire()



class Women:
    def __init__(self, name):
        self.name = name
        # 私有属性
        self.__age = 18

    # 私有方法
    def __secret(self):
        print('%s 的年龄是 %d' % (self.name, self.__age))

xiaofang = Women('小芳')
# 伪私有属性、伪私有方法 在外部不能被访问
print(xiaofang._Women__age)
# print(xiaofang.__age)
# 伪私有属性、伪私有方法 在内部可以被访问
# xiaofang.secret()
xiaofang._Women__secret()
